package com.cpp.common.utils;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;

import java.util.*;

public class RedisZSetUtil {

    private static StringRedisTemplate redisTemplate;

    /**
     * 静态注入初始化方法（由Spring调用）
     */
    public static void setRedisTemplate(StringRedisTemplate redisTemplate) {
        RedisZSetUtil.redisTemplate = redisTemplate;
    }

    // ================== 原有功能 ==================

    /**
     * 增加元素的出现次数（使用 ZINCRBY 命令）
     *
     * @param key       Redis中的zset键
     * @param element   元素名称
     * @param increment 增量（一般为1）
     */
    public static void incrementElementCount(String key, String element, double increment) {
        redisTemplate.opsForZSet().incrementScore(key, element, increment);
    }

    /**
     * 获取元素的出现次数（即当前分数）
     *
     * @param key      Redis中的zset键
     * @param element  元素名称
     * @return         出现次数（Double类型）
     */
    public static Double getElementCount(String key, String element) {
        return redisTemplate.opsForZSet().score(key, element);
    }

    /**
     * 获取某个元素在 zset 中的排名（按分数从高到低）
     *
     * @param key      Redis中的zset键
     * @param element  元素名称
     * @return         排名（从0开始）
     */
    public static Long getRank(String key, String element) {
        return redisTemplate.opsForZSet().reverseRank(key, element);
    }
    /**
     * 获取排名前十的元素
     */
    public static Set<ZSetOperations.TypedTuple<String>> getTopTenElements(String key) {
        Set<ZSetOperations.TypedTuple<String>> topTenElements = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, 9);
        return topTenElements;
    }

    /**
     * 获取 zset 中所有元素及其分数（可用于排行榜等）
     *
     * @param key Redis中的zset键
     * @return Set<ZSetOperations.TypedTuple<String>>
     */
    public static Set<ZSetOperations.TypedTuple<String>> getZSetEntries(String key) {
        return redisTemplate.opsForZSet().rangeWithScores(key, 0, -1);
    }

    // ================== 新增功能：导入数列 ==================

    /**
     * 将本地的数值序列导入到 Redis 的 Sorted Set 中
     *
     * @param key       Redis 中的 zset 键
     * @param data      数值序列（如 List<Double>）
     * @param prefix    每个元素的前缀（用于生成唯一标识符）
     *                  例如："item_" + index -> item_0, item_1 ...
     */
    public static void importNumericalSeriesToZSet(String key, List<Double> data, String prefix) {
        if (data == null || data.isEmpty()) {
            return;
        }

        // 删除原有数据（可选）
        redisTemplate.delete(key);

        // 批量添加
        for (int i = 0; i < data.size(); i++) {
            String element = prefix + i;
            redisTemplate.opsForZSet().add(key, element, data.get(i));
        }
    }

    /**
     * 将本地的数值数组转换为 List<Double> 后导入到 Redis 的 Sorted Set 中
     *
     * @param key       Redis 中的 zset 键
     * @param array     数值数组（double[]）
     * @param prefix    每个元素的前缀（用于生成唯一标识符）
     */
    public static void importNumericalArrayToZSet(String key, double[] array, String prefix) {
        List<Double> dataList = new ArrayList<>();
        for (double value : array) {
            dataList.add(value);
        }
        importNumericalSeriesToZSet(key, dataList, prefix);
    }

    /**
     * 导入原始数值列表，使用默认前缀 "element_"
     */
    public static void importNumericalSeriesToZSet(String key, List<Double> data) {
        importNumericalSeriesToZSet(key, data, "element_");
    }

    /**
     * 导入原始数值数组，使用默认前缀 "element_"
     */
    public static void importNumericalArrayToZSet(String key, double[] array) {
        importNumericalArrayToZSet(key, array, "element_");
    }
}